/**
 * Project: topdt-jbpm
 * Copyright 2013  Top Digital Technology  Co. Ltd.
 * All right reserved.
 */
package com.topdt.jbpm.form;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.thx.common.spring.BeanFactory;
import com.thx.common.util.AppContext;
import com.topdt.jbpm.dao.FormInstanceDao;
import com.topdt.jbpm.form.FormUI.UIType;
import com.topdt.jbpm.form.query.Option;
import com.topdt.jbpm.model.Application;
import com.topdt.jbpm.model.Field;
import com.topdt.jbpm.model.Form;
import com.topdt.jbpm.model.FormInstance;
import com.topdt.jbpm.model.Work;
import com.topdt.jbpm.service.FieldService;
import com.topdt.jbpm.service.FormInstanceManager;
import com.topdt.jbpm.utils.ControlUtils;
import com.topdt.jbpm.utils.FreeMakerUtils;

import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 建立日期 : 2013-4-14 下午3:24:57<br>
 * 作者 : balance<br>
 * 模块 : <br>
 * 描述 : 表单装配器<br>
 * 修改历史: 序号 日期 修改人 修改原因 <br>
 * 1 <br>
 * 2 <br>
 */
public class GeneralFormHandle extends AbstractGeneralFormHandle {
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public Document getDocument(String workId) {
		FormInstanceManager fIService = (FormInstanceManager) BeanFactory.getBean("formInstanceManager");
		FormInstance fi = fIService.getById(workId);
		if (fi == null) {
			fi = new FormInstance();
			fi.setDocId(workId);
		}		
		Map<String,String> map = fIService.getDataById(workId);
		if(map!=null){
			Map<String, Object> newMap = new HashMap<String, Object>();
			for(String key :map.keySet()){
				newMap.put(key, map.get(key));
			}
			fi.setDataMap(newMap);
		}
		return fi;
	}

	@Override
	public Document convert2Doc(Map<String, String[]> parameter) {
		Map<String, String> resultMap = new HashMap<String, String>();
		for (String key : parameter.keySet()) {
			System.out.println(key);
			System.out.println();
			String[] values = parameter.get(key);
			if (values.length > 1) {
				String obj = "";
				for (String s : values) {
					obj += s + ";";
				}
				resultMap.put(key, obj.substring(0, obj.length() - 1));
			} else if (values.length > 0) {
				resultMap.put(key, values[0]);
			}
		}
		Object aa = JSON.toJSON(resultMap);
		byte[] data;
		FormInstance formIn = new FormInstance();
		try {
			data = aa.toString().getBytes("utf-8");
			formIn.setFormData(data);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return formIn;
	}

	@Override
	public Document saveDoc(Document doc) {
		FormInstance formIn = (FormInstance) doc;
		formIn.setCompanyId(AppContext.getCurrentComId());
		formIn.setUpdateTime(new Timestamp(System.currentTimeMillis()));
		FormInstanceDao dao = (FormInstanceDao) BeanFactory.getBean("formInstanceDao");
		dao.saveOrUpdate(formIn);

		return formIn;
	}

	@Override
	public void deleteDoc(String documentId) {
		FormInstanceDao dao = (FormInstanceDao) BeanFactory.getBean("formInstanceDao");
		dao.deleteById(documentId);
	}

	@Override
	protected FormUI generateFormUI(Application app, Map<String, String> fieldControl, Map<String, String> funControl, Document doc, Map<String, Object> context, Work work) {
		FormUI ui = new FormUI(fieldControl, funControl, doc);
		ui.setContext(context);
		ui.setUiType(UIType.textHtml);
		// ??
		// --获得模板
		Template template = null;
		Form form = app.getForm();
		try {
			if (form.getTempletStorageType() != null && !"".equals(form.getTempletStorageType())
					&& "byte".equals(form.getTempletStorageType())) {
				if (context.get("isView") != null && (Boolean) context.get("isView")) {
					String tempStr = new String(form.getTempletByte(), "utf-8");
					String temp = TemplateCreater.mergeTemplate(tempStr);// --先合并
					String htmlSource = TemplateCreater.getViewHtmlByTemplate(temp);
					template = FreeMakerUtils.getTemplateByForm(htmlSource.getBytes("utf-8"));
				} else if (context.get("isMobile") != null && (Boolean) context.get("isMobile")) {
					String tempStr = new String(form.getMobileTemplateByte(), "utf-8");
					String htmlSource = TemplateCreater.mergeMobileTemplateWithHtmlSource("pages/workflow/templates/appTemplates/template.html", tempStr);
					template = FreeMakerUtils.getTemplateByForm(htmlSource.getBytes("utf-8"));
				} else {
					String tempStr = new String(form.getTempletByte(), "utf-8");
					String opnHtml=TemplateCreater.opnTml(app.getAppId());
					context.put("opinionHtml", opnHtml);
					String temp = TemplateCreater.mergeTemplate(tempStr);// --先合并
					template = FreeMakerUtils.getTemplateByForm(temp.getBytes("utf-8"));
				}
			} else if ("file".equals(form.getTempletStorageType())) {
				template = FreeMakerUtils.getTemplate(form.getTempletPath(), "");// TODO
																					// 调整模板路径

			}
		} catch (IOException e) {
			logger.error("<错误>模板文件不存在或路径错误！" + e.toString());
			ui.setUiText("模板文件不存在或路径错误！");
			return ui;
		}
		if (template == null) {
			return ui;
		}
		String result = "无显示的内容";
		Writer out = new StringWriter();
		try {
			template.process(context, out);
		} catch (TemplateException e) {
			logger.error("<错误>模板文件不存在或路径错误！" + e.toString());
			ui.setUiText("模板文件不存在或路径错误！");
			return ui;
		} catch (IOException e) {
			logger.error("<错误>模板文件不存在或路径错误！" + e.toString());
			ui.setUiText("模板文件不存在或路径错误！");
			return ui;
		}
		result = out.toString();
		ui.setUiText(result);
		return ui;
	}

	/**
	 * @Description : 获取表单字段权限(不同流程节点读写性)
	 * @Method_Name : getFieldAuthorityContext
	 * @param app
	 * @param fieldControl
	 * @param doc
	 * @param context
	 * @param work
	 * @return
	 * @Creation Date : 2015年3月10日 下午6:54:59
	 * @version : v1.00
	 * @Author : calonlan
	 * @Update Date : 2015年3月10日 下午6:54:59
	 * @Update Author : calonlan
	 */
	@Override
	protected Map<String, Object> getFieldAuthorityContext(Application app, Map<String, String> fieldControl, Document doc, Map<String, Object> context, Work work) {
		Map<String, Object> value = new HashMap<String, Object>();
		FormInstance formInstance = (FormInstance) doc;
		if (formInstance.getFormData() == null) {
			value = null;
		} else {
			try {
				value = JSON.parseObject(new String(formInstance.getFormData(), "utf-8"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		FieldService fieldService = (FieldService) BeanFactory.getBean("fieldService");
		List<Field> fields = fieldService.getFieldsByformId(app.getForm().getFormId());
		if (fields != null && fields.size() > 0) {
			for (Field field : fields) {
				String fieldName = field.getFieldName();
				logger.debug("<提示>:字段名" + fieldName);
				Map att = new HashMap();
				context.put(fieldName, att);
				if (fieldControl != null && fieldControl.size() > 0) {
					if (ControlUtils.getReadValue(fieldControl.get(fieldName)))
						att.put("readonly", "readonly");
					if (!ControlUtils.getShowValue(fieldControl.get(fieldName)))
						att.put("show", "display:none");
				} else {
					// -- 没有控制时 默认起草时为可编辑
					if (!work.getWorkState().equals(Work.STATE_START)) {
						att.put("readonly", "readonly");
					}
				}
				SysParamService sysParamService = (SysParamService) BeanFactory.getBean(SysParamService.class);
				if (value != null && value.size() != 0 && value.get(fieldName) != null) {
					if (context.get("isView") != null && (Boolean) context.get("isView")) {
						if ("radio".equals(field.getFieldType()) || "checkbox".equals(field.getFieldType())
								|| "select".equals(field.getFieldType())) {
							Option option = sysParamService.getOptionName((String) value.get(fieldName), "more");
							att.put("text", option.getName());
						} else if ("tree".equals(field.getFieldType())) {
							Option option = sysParamService.getOptionName((String) value.get(fieldName), "tree");
							att.put("text", option.getName());
						} else {
							att.put("value", value.get(fieldName));
						}
					} else {
						if (context.get("isMobile") != null && (Boolean) context.get("isMobile")
								&& "richTextEditer".equals(field.getFieldType())) {
							String richTextvalue = (String) value.get(fieldName);
							richTextvalue = Jsoup.clean(richTextvalue, Whitelist.none());
							att.put("value", richTextvalue);
						} else {
							att.put("value", value.get(fieldName));
						}
					}
				}
				if ("systemVar".equals(field.getFieldType())) {
					Option option = sysParamService.getOptionName(field.getFieldOption(), "system");
					context.put(option.getValue(), SystemVarEval.getValue(field.getFieldOption()));
				}

			}
		}
		return context;
	}

	@Override
	public void executeBusiness(Application app, Work work) {
		// TODO Auto-generated method stub
	}

	@Override
	public List<Field> getFields(Application app) {
		FieldService fieldService=(FieldService)BeanFactory.getBean("fieldService");
		List<Field> fields=fieldService.getFieldsByformId(app.getForm().getFormId());
		return fields;
	}

}
